﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Xml;
using Av.Utils;

namespace JrcUtils
{

    class TradestationSystemInfo
    {
        /// <summary>
        /// Gets/sets WindowHandle
        /// </summary>
        public string WindowHandle { get; set; }
        /// <summary>
        /// Gets/sets WorkspaceName
        /// </summary>
        public string WorkspaceName { get; set; }
        /// <summary>
        /// Gets/sets WindowID
        /// </summary>
        public string WindowID { get; set; }
        /// <summary>
        /// Gets/sets System
        /// </summary>
        public string System { get; set; }
        /// <summary>
        /// Gets/sets Commission
        /// </summary>
        public string Commission { get; set; }
        /// <summary>
        /// Gets/sets Slippage
        /// </summary>
        public string Slippage { get; set; }
        /// <summary>
        /// Gets/sets PointValue
        /// </summary>
        public string PointValue { get; set; }
        /// <summary>
        /// Gets/sets PriceConversion
        /// </summary>
        public string PriceConversion { get; set; }
        /// <summary>
        /// Gets/sets Margin
        /// </summary>
        public string Margin { get; set; }
        /// <summary>
        /// Gets/sets Symbol
        /// </summary>
        public string Symbol { get; set; }
        /// <summary>
        /// Gets/sets Description
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// Gets/sets Compression
        /// </summary>
        public string Compression { get; set; }
        /// <summary>
        /// Gets/sets VersionType
        /// </summary>
        public string VersionType { get; set; }
        /// <summary>
        /// Gets/sets PerUnitCommission
        /// </summary>
        public string PerUnitCommission { get; set; }
        /// <summary>
        /// Gets/sets PerUnitSlippage
        /// </summary>
        public string PerUnitSlippage { get; set; }
        /// <summary>
        /// Gets/sets InitialCapital
        /// </summary>
        public string InitialCapital { get; set; }
        /// <summary>
        /// Gets/sets InterestRate
        /// </summary>
        public string InterestRate { get; set; }
        /// <summary>
        /// Gets/sets AccountLocaleID
        /// </summary>
        public string AccountLocaleID { get; set; }
        /// <summary>
        /// Gets/sets CounterCurrencyLocaleID
        /// </summary>
        public string CounterCurrencyLocaleID { get; set; }
        /// <summary>
        /// Gets/sets BaseCurrencyLocaleID
        /// </summary>
        public string BaseCurrencyLocaleID { get; set; }
        /// <summary>
        /// Gets/sets AccountLotSize
        /// </summary>
        public string AccountLotSize { get; set; }
        /// <summary>
        /// Gets/sets Input
        /// </summary>
        public string InputOne { get; set; }
        /// <summary>
        /// Gets/sets Input
        /// </summary>
        public string InputTwo { get; set; }


        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("{0,-24}{1}", "WindowHandle", WindowHandle).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "WorkspaceName", WorkspaceName).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "WindowID", WindowID).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "System", System).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Commission", Commission).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Slippage", Slippage).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "PointValue", PointValue).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "PriceConversion", PriceConversion).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Margin", Margin).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Symbol", Symbol).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Description", Description).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Compression", Compression).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "VersionType", VersionType).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "PerUnitCommission", PerUnitCommission).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "PerUnitSlippage", PerUnitSlippage).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "InitialCapital", InitialCapital).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "InterestRate", InterestRate).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "AccountLocaleID", AccountLocaleID).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "CounterCurrencyLocaleID", CounterCurrencyLocaleID).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "BaseCurrencyLocaleID", BaseCurrencyLocaleID).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "AccountLotSize", AccountLotSize).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Input1", InputOne).AppendLine();
            sb.AppendFormat("{0,-24}{1}", "Input2", InputTwo).AppendLine();



            return sb.ToString();
        }
    }

    class Tradestation
    {
        /// <summary>
        /// First part - entry
        /// </summary>
        public TradestationLine Entry { get; set; }

        /// <summary>
        /// Last part - exit
        /// </summary>
        public TradestationLine Exit { get; set; }

        public string ToCsv()
        {
            return string.Format("{1}{0}{2}", Environment.NewLine, Entry.ToCsv(), Exit.ToCsv());
        }

        public static DateTime ParseXmlDate(XmlNodeList xmlNodeList)
        {
            DateTime dt = DateTime.MinValue;
            string s = "yyyy-MM-dd HH:mm:ss";

            // Default value for seconds if not present in XML
            string seconds = "00";

            foreach(XmlNode node in xmlNodeList)
            {
                switch( node.Name.ToLower() )
                {
                    case "year":
                        Log4cs.Log(Importance.Debug, "Got year: {0}", node.FirstChild.Value);
                        s = s.Replace("yyyy", node.FirstChild.Value);
                        Log4cs.Log(Importance.Debug, "Replaced year in string: {0}", s);
                        break;
                    case "month":
                        Log4cs.Log(Importance.Debug, "Got month: {0}", node.FirstChild.Value);
                        s = s.Replace("MM", node.FirstChild.Value);
                        break;
                    case "day":
                        Log4cs.Log(Importance.Debug, "Got day: {0}", node.FirstChild.Value);
                        s = s.Replace("dd", node.FirstChild.Value);
                        break;
                    case "hour":
                        Log4cs.Log(Importance.Debug, "Got hour: {0}", node.FirstChild.Value);
                        s = s.Replace("HH", node.FirstChild.Value);
                        break;
                    case "minute":
                        Log4cs.Log(Importance.Debug, "Got minute: {0}", node.FirstChild.Value);
                        s = s.Replace("mm", node.FirstChild.Value);
                        break;
                    case "second":
                        //Log4cs.Log(Importance.Debug, "Got second: {0}", node.FirstChild.Value);
                        // It will be replaced after loop
                        seconds = node.FirstChild.Value;
                        break;
                }
            }

            // Replace "ss" with seconds from XML or default value
            s = s.Replace("ss", seconds);
            Log4cs.Log("XML DateTime joined to string is: {0}...", s);

            return DateTime.Parse(s);
        }
    }

    class TradestationLine
    {

        public int Id { get; set; }

        /// <summary>
        /// Type of Tradestation item - Buy, Sell, etc...
        /// </summary>
        public string EntryType { get; set; }

        public DateTime Date { get; set; }

        public string Signal { get; set; }

        public string CurrencyCode { get; set; }

        public float Price { get; set; }

        public string PriceCsv
        {
            get
            {
                CultureInfo ci = CultureInfo.GetCultureInfo("en-us");
                return string.Format(CultureInfo.CreateSpecificCulture("en-us"), "{0}{1:0.00000}", CurrencyCode, Price);
            }
        }

        public float RollOverPips { get; set; }

        // TODO: add other fields :)


        public string ToCsv()
        {
            return string.Format(
                "{0},{1},{2},{3},{4},{5},,,,,"
                , Id > 0 ? Id.ToString() : ""
                , EntryType
                , Date.ToString("yyyy-MM-dd HH:mm")
                , Signal
                , PriceCsv
                , RollOverPips
                );
        }

        public static TradestationLine ParseXmlNode(XmlNode tradeNode)
        {
            TradestationLine tl = new TradestationLine();
            foreach(XmlNode child in tradeNode.ChildNodes)
            {
                Log4cs.Log(Importance.Debug, "Trade: {0}", child.Name);
                switch(child.Name.ToLower())
                {
                    case "date":
                        tl.Date = Tradestation.ParseXmlDate(child.ChildNodes);
                        break;
                    case "type":
                        tl.EntryType = child.FirstChild.Value;
                        break;
                    case "price":
                        tl.Price = float.Parse(child.FirstChild.Value);
                        break;
                    default:
                        Log4cs.Log(Importance.Warning, "<Trade> does not handle {0}!", child.Name);
                        break;
                }
            }  // END FOREACH ( list all trade elements )

            return tl;
        }
    }
}
